<?php

/**
 * @am_plugin_api 6.0
*/
class Am_Plugin_SubscriptionLimit extends Am_Plugin
{
    const PLUGIN_STATUS = self::STATUS_PRODUCTION;
    const PLUGIN_REVISION = '6.3.32';

    protected $_configPrefix = 'misc.';

    static function getEtXml()
    {
        return <<<CUT
<table_data name="email_template">
    <row type="email_template">
        <field name="name">misc.subscription-limit.notify_oos_admin</field>
        <field name="email_template_layout_id">2</field>
        <field name="lang">en</field>
        <field name="format">text</field>
        <field name="subject">%site_title%: Out of stock - %product.title%</field>
        <field name="txt">
%product.title% is out of stock.
        </field>
    </row>
    <row type="email_template">
        <field name="name">misc.subscription-limit.notify_ls_admin</field>
        <field name="email_template_layout_id">2</field>
        <field name="lang">en</field>
        <field name="format">text</field>
        <field name="subject">%site_title%: Low stock - %product.title% (%qty%)</field>
        <field name="txt">
%product.title% is low stock.
Remaining quantity is %qty%
        </field>
    </row>
</table_data>
CUT;
    }

    function onSetupEmailTemplateTypes(Am_Event $event)
    {
        $event->addReturn([
            'id' => 'misc.subscription-limit.notify_oos_admin',
            'title' => ___('Out of Stock Notification to Admin'),
            'mailPeriodic' => Am_Mail::ADMIN_REQUESTED,
            'isAdmin' => true,
            'vars' => ['product.title' => ___('Product Title')],
        ], 'misc.subscription-limit.notify_oos_admin');
        $event->addReturn([
            'id' => 'misc.subscription-limit.notify_ls_admin',
            'title' => ___('Low Stock Notification to Admin'),
            'mailPeriodic' => Am_Mail::ADMIN_REQUESTED,
            'isAdmin' => true,
            'vars' => [
                'product.title' => ___('Product Title'),
                'qty' => ___('Remaining quantity')
            ],
        ], 'misc.subscription-limit.notify_ls_admin');
    }

    function init()
    {
        $this->getDi()->productTable->customFields()
            ->add(new Am_CustomFieldText('subscription_limit', ___('Subscription limit'), ___('limit amount of subscription for this product, keep empty if you do not want to limit amount of subscriptions')));
        $this->getDi()->productTable->customFields()
            ->add(new Am_CustomFieldText('subscription_user_limit', ___('Subscription limit for each user'), ___('limit amount of subscription for this product per user, keep empty if you do not want to limit amount of subscriptions')));
    }

    function getTitle()
    {
        return ___('Subscription Limit');
    }

    function _initSetupForm(Am_Form_Setup $form)
    {
        $form->addElement('email_checkbox', 'notify_oos_admin')
            ->setLabel(___('Out of Stock Notification'));
        $form->addElement('email_checkbox', 'notify_ls_admin')
            ->setLabel(___('Low Stock Notification'));
        $form->addText('low_stock_threshold',
            ['size'=>3, 'placeholder'=>'3', 'id' => 'ls-threshold'])
            ->setLabel(___('Low Stock Threshold'));
        $form->addScript()
            ->setScript(<<<CUT
jQuery(function(){
    jQuery('[name$=notify_ls_admin]').change(function(){
        jQuery('#ls-threshold').closest('.am-row').toggle(this.checked);
    }).change();
});
CUT
            );
    }

    function onInvoiceBeforePayment(Am_Event $event)
    {
        /* @var $invoice Invoice */
        $invoice = $event->getInvoice();
        $user = $invoice->getUser();

        foreach ($invoice->getItems() as $item)
        {
            if ($item->item_type != 'product') continue;
            $product = $this->getDi()->productTable->load($item->item_id);
            if (($limit = $product->data()->get('subscription_limit')) &&
                $limit < $item->qty) {

                throw new Am_Exception_InputError(___('There is not such amount (%d) of product %s', $item->qty, $item->item_title));
            }

            $count = $this->getDi()->db->selectCell("
                SELECT SUM(ii.qty)
                FROM ?_invoice_item ii LEFT JOIN ?_invoice i ON ii.invoice_id = i.invoice_id
                WHERE i.user_id = ? and ii.item_id=? and i.status<>0 and i.invoice_id <> ?d
                ", $user->pk(), $product->pk(), $invoice->pk());
            if (($limit = $product->data()->get('subscription_user_limit')) &&
                $limit < ($item->qty + $count)) {

                throw new Am_Exception_InputError(___('There is not such amount (%d) of product %s you can purchase only %s items.', $item->qty, $item->item_title, $limit));
            }
        }
    }

    function onInvoiceStarted(Am_Event_InvoiceStarted $event)
    {
        $invoice = $event->getInvoice();
        foreach ($invoice->getItems() as $item) {
            if ($item->item_type != 'product') continue;
            $product = $this->getDi()->productTable->load($item->item_id);

            if ($limit = $product->data()->get('subscription_limit')) {
                $limit -= $item->qty;
                $product->data()->set('subscription_limit', $limit);
                if ($limit && $limit<=$this->getConfig('low_stock_threshold', 3) && $this->getConfig('notify_ls_admin')) {
                    $et = Am_Mail_Template::load('misc.subscription-limit.notify_ls_admin');
                    $et->setProduct($product);
                    $et->setQty($limit);
                    $et->sendAdmin();
                }

                if (!$limit) {
                    if ($this->getConfig('notify_oos_admin')) {
                        $et = Am_Mail_Template::load('misc.subscription-limit.notify_oos_admin');
                        $et->setProduct($product);
                        $et->sendAdmin();
                    }

                    $product->is_disabled = 1;
                }
                $product->save();
            }
        }
    }

    function onGridProductInitGrid(Am_Event_Grid $event)
    {
        $grid = $event->getGrid();
        $grid->addField(new Am_Grid_Field('subscription_limit', ___('Limit'), false))->setRenderFunction([$this, 'renderLimit']);
    }

    function renderLimit(Product $product)
    {
        return '<td align="center">' . ( ($limit = $product->data()->get('subscription_limit')) ? $limit : '&ndash;')  . '</td>';
    }
}